<template>
    <div class="app-container">
        <div class="class-table">
            <!-- 下拉选择学期 -->
            <el-select
                class="semester-select"
                v-model="semesterId"
                placeholder="请选择学期"
                @change="changeSemester"
                clearable
            >
                <el-option
                    v-for="item in semesterData"
                    :key="item.id"
                    :value="item.id"
                    :label="item.semesterName"
                ></el-option>
            </el-select>
            <!-- 下拉选择班级 -->
            <el-select
                class="class-select"
                @change="handleSelectClass"
                @clear="clearListener"
                clearable
                v-model="classNo"
                placeholder="请选择班级"
            >
                <el-option
                    v-for="item in classData"
                    :key="item.classNo" 
                    :value="item.classNo"
                    :label="item.className"
                ></el-option>
            </el-select>
            <el-select
                class="class-select"
                @change="handleSelectRoom"
                @clear="clearListener"
                clearable
                v-model="roomNo"
                placeholder="请选择教室"
            >
                <el-option
                    v-for="item in roomData"
                    :key="item.roomNo" 
                    :value="item.roomNo"
                    :label="item.roomName"
                ></el-option>
            </el-select>
            <el-select
                class="class-select"
                @change="handleSelectTeacher"
                @clear="clearListener"
                clearable
                v-model="teacherNo"
                placeholder="请选择教师"
            >
                <el-option
                    v-for="item in teacherData"
                    :key="item.teacherNo" 
                    :value="item.teacherNo"
                    :label="item.teacherName"
                ></el-option>
            </el-select>
            <div style="width: 10px; display: inline-block"></div>
            <el-button
                :type="srcId ? 'danger' : (chooseType.value === 0 ? 'success' : 'primary')"
                @click="toggleChooseType"
            >
                {{ srcId ? '点击选择移动(新)' : (chooseType.value === 0 ? '选择目的时间' : '选择待移动课') }}
            </el-button>
            <el-button
                type="primary"
                @click="adjustConfirm"
                :disabled="srcId == null || destTimeslot == -1"
            >
                手动处理排课
            </el-button>
        </div>
        <br />
        <el-table
            :data="classTableData.lessons"
            border
            style="width: 100%"
            id="my-table"
            @cell-click="handleCellClick" 
        >
            <!-- 时间列 -->
            <el-table-column prop="name" label="时间" width="100" align="center">
                <template #default="scope">
                    <p>{{ digital2Chinese(scope.$index + 1) }}</p>
                    <p class="period">{{ scope.row }}</p>
                </template>
            </el-table-column>

            <!-- 周次和课程信息列 -->
            <el-table-column
                v-for="(weekNum, weekIndex) in classTableData.courses" 
                :key="weekIndex"
                :label="'周' + digital2Chinese(weekIndex + 1, 'week')"
                width="170"
                header-align="center"
            >
                <template #default="scope">
                    <div
                        class="course-info"
                        :data-timeslot="classTableData.timeslot[weekIndex][scope.$index]" 
                        :data-row="scope.$index" 
                        :data-col="weekIndex" 
                    >
                        <span
                            class="span"
                            style="background-color: lightgreen"
                            v-if="destRow.value == scope.$index && destCol.value == weekIndex"
                        >
                            目的时间
                        </span>

                        <span
                            class="span"
                            style="background-color: rgb(241, 253, 241); color:gray"
                            v-if="inRecommendDest(weekIndex, scope.$index)"
                        >
                            推荐目的时间
                        </span>

                        <div
                            @click.stop="clickCard" 
                            v-for="(t, i) in convertMsgToList(
                                classTableData.courses[weekIndex][scope.$index]
                            )"
                            :key="i" 
                            class="mycard"
                        >
                            <span
                                :data-timetableid="convertIdToList(classTableData.timetableId[weekIndex][scope.$index])[i]"
                                :data-timeslot="classTableData.timeslot[weekIndex][scope.$index]" 
                                :data-row="scope.$index" 
                                :data-col="weekIndex" 
                                class="span"
                                style="background-color: blue; color: white;"
                                v-show="srcId && convertIdToList(classTableData.timetableId[weekIndex][scope.$index])[i] == srcId.value"
                            >
                                待移动课
                            </span>
                            {{ t }}
                        </div>
                    </div>
                </template>
            </el-table-column>
        </el-table>
    </div>
</template>

<script setup>
import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import axios from 'axios';

// const { proxy } = getCurrentInstance(); // For $axios, $store

const chooseType = ref(0); // 0 for selecting destination, 1 for selecting course to move

const toggleChooseType = () => {
    chooseType.value = chooseType.value === 0 ? 1 : 0;
    // 切换模式时，清空之前的选择是个好习惯，确保状态一致性
    // 如果 clearAdjustPick() 应该在切换时调用，请确保它在这里被调用或已在其他地方处理
    // clearAdjustPick(); 
};

const classData = ref([]);
const roomData = ref([]);
const teacherData = ref([]);
const semesterData = ref([]);
const classNo = ref("");
const roomNo = ref("");
const teacherNo = ref("");
const semesterId = ref(null); // Initialize with null or a default value
const listLoading = ref(true);

const classTableData = reactive({
    lessons: [
        "08.20-09.55",
        "10.15-11.50",
        "14.20-15.55",
        "16.15-17.50",
        "18.30-20.05",
    ],
    courses: [[], [], [], [], [], [], []],
    timetableId: [[], [], [], [], [], [], []],
    timeslot: [[], [], [], [], [], [], []],
});

const recommendDest = ref([]);
const srcId = ref(null);
const srcRow = ref(-1);
const srcCol = ref(-1);
const srcTimeslot = ref(-1);
// const destId = ref(null); // destId was not used in the original logic for adjustConfirm
const destRow = ref(-1);
const destCol = ref(-1);
const destTimeslot = ref(-1);

const initClassTableData = () => {
    classTableData.courses = [[], [], [], [], [], [], []];
    classTableData.timetableId = [[], [], [], [], [], [], []];
    classTableData.timeslot = [[], [], [], [], [], [], []];
    // lessons remain static
    return true;
};

const setToTable = (ret) => {
    initClassTableData();

    let level = 0;
    let beforeTimeslot = -1;
    let dataIndex = 0; // Use a separate index for ret array

    for (let ts = 0; ts < 35; ts++) {
        level = Math.floor(ts / 5);
        const currentRow = ts % 5;

        // Ensure arrays are initialized for the current level if not already
        if (!classTableData.courses[level]) classTableData.courses[level] = [];
        if (!classTableData.timetableId[level]) classTableData.timetableId[level] = [];
        if (!classTableData.timeslot[level]) classTableData.timeslot[level] = [];

        let foundMatch = false;
        let currentTimeslotEntries = [];
        let currentTimeslotIds = [];

        // Collect all entries for the current timeslot (ts)
        while(dataIndex < ret.length && parseInt(ret[dataIndex].timeslot) === ts){
            const item = ret[dataIndex];
            let section =
                "(" +
                ((item.timeslot % 5) * 2 + 1) +
                "-" +
                ((item.timeslot % 5) * 2 + 2) +
                "节)";
            let biweekly =
                item.biweekly == 1 ? "(单)" : item.biweekly == 2 ? "(双)" : "";
            let time =
                section + item.startWeek + "-" + item.endWeek + "周" + biweekly;
            let className = item.className;
            let teacherName = item.teacherName;
            let roomName = item.roomName;
            let course = item.courseNo + "-" + item.courseName;
            let size = item.size;

            let msg =
                time +
                "/" +
                className +
                "/" +
                teacherName +
                "/" +
                roomName +
                "/" +
                course +
                "/" +
                "选课人数：" +
                size;
            currentTimeslotEntries.push(msg);
            currentTimeslotIds.push(item.id);
            dataIndex++;
            foundMatch = true;
        }

        if (foundMatch) {
            classTableData.courses[level][currentRow] = currentTimeslotEntries.join("@@@");
            classTableData.timetableId[level][currentRow] = currentTimeslotIds.join("@@@");
        } else {
            classTableData.courses[level][currentRow] = "";
            classTableData.timetableId[level][currentRow] = -1; // Or an empty string if preferred for non-existent IDs
        }
        classTableData.timeslot[level][currentRow] = ts;
    }

    if (ret.length === 0 && semesterId.value) { // Only show message if a semester is selected
        ElMessage.success("当前条件下暂无课表");
    }
    // console.log('classTableData updated', JSON.parse(JSON.stringify(classTableData)));
};

const fetchData = async (url) => {
    listLoading.value = true;
    try {
        const res = await axios.get(url, {
            headers: {
                token: localStorage.getItem("token"),
            },
        });
        setToTable(res.data.data || []);
    } catch (error) {
        console.error("获取课表数据失败:", error);
        ElMessage.error("获取课表数据失败");
        setToTable([]); // Clear table on error
    } finally {
        listLoading.value = false;
    }
};

const getList = () => {
    if (!semesterId.value) {
        setToTable([]); // Clear table if no semester is selected
        listLoading.value = false;
        return;
    }
    // /${semesterId.value}
    // fetchData(`/api/timetable/getList`);
};

const queryClass = () => {
    if (!semesterId.value || !classNo.value) return;
    fetchData(`/api/timetable/class/${semesterId.value}/${classNo.value}`,{
      headers: {
        "token": localStorage.getItem("token"),
      },
    });
};

const queryRoom = () => {
    if (!semesterId.value || !roomNo.value) return;
    fetchData(`/api/timetable/room/${semesterId.value}/${roomNo.value}`,{
      headers: {
        "token": localStorage.getItem("token"),
      },
    });
};

const queryTeacher = () => {
    if (!semesterId.value || !teacherNo.value) return;
    fetchData(`/api/timetable/teacher/${semesterId.value}/${teacherNo.value}`,{
      headers: {
        "token": localStorage.getItem("token"),
      },
    });
};

const fetchSelectOptions = async (url, dataRef, entityName) => {
    try {
        const res = await axios.get(url,{
          headers: {
            "token": localStorage.getItem("token"),
          },
        });
        dataRef.value = res.data.data || [];
    } catch (error) {
        console.error(`查询${entityName}列表失败`, error);
        ElMessage.error(`查询${entityName}列表失败`);
    }
};

const getSemester = () => fetchSelectOptions("/api/semester/getList", semesterData, "学期");
const getClass = () => fetchSelectOptions("/api/classes/getList", classData, "班级");
const getTeacher = () => fetchSelectOptions("/api/teacher/getList", teacherData, "教师");
const getRoom = () => fetchSelectOptions("/api/room/getList", roomData, "教室");

onMounted(() => {
    // Attempt to get semesterId from store or a default
    // const storeSemesterId = proxy.$store?.getters?.getSemesterId; // Safely access store
    // if (storeSemesterId) {
    //     semesterId.value = storeSemesterId;
    // }
    getList(); // Initial load based on semesterId (might be null)
    getSemester();
    getClass();
    getRoom();
    getTeacher();
});

const changeSemester = () => {
    clearListener();
    clearAdjustPick();
    getList();
};

const inRecommendDest = (weekIndex, scopeIndex) => {
    if (recommendDest.value.length === 0) return false;
    const timeslotValue = weekIndex * 5 + scopeIndex;
    return recommendDest.value.includes(timeslotValue);
};

const clickCard = (event) => {
    if (chooseType.value !== 1) return; // 当不是“选择待移动课”模式时，不执行
    const targetSpan = event.currentTarget.querySelector('span[data-timetableid]');
    if (!targetSpan) return;

    const id = targetSpan.getAttribute("data-timetableid");
    const row = targetSpan.getAttribute("data-row");
    const col = targetSpan.getAttribute("data-col");
    const timeslot = targetSpan.getAttribute("data-timeslot");

    if (!id || id === '-1' || id === "") return;

    if (srcId.value == id) {
        clearAdjustPick();
        return;
    }
    srcRow.value = parseInt(row);
    srcCol.value = parseInt(col);
    srcId.value = id;
    srcTimeslot.value = parseInt(timeslot);

    getConflictList(id);
    rehearsalChangeTimeslot(id);
};

const convertIdToList = (idStr) => {
    if (!idStr || idStr === '-1') return ["-1"]; // Ensure it returns an array even for single or no ID
    return String(idStr).split("@@@");
};

const convertMsgToList = (msgStr) => {
    if (!msgStr) return [];
    return String(msgStr).split("@@@");
};

const handleCellClick = (row, column, cell, event) => {
    if (chooseType.value !== 0) return; // 当不是“选择目的时间”模式时，不执行
    // Find the .course-info div to get data attributes
    let courseInfoDiv = event.target;
    while(courseInfoDiv && !courseInfoDiv.classList.contains('course-info')){
        courseInfoDiv = courseInfoDiv.parentElement;
    }
    if(!courseInfoDiv) return;

    const r = courseInfoDiv.getAttribute("data-row");
    const c = courseInfoDiv.getAttribute("data-col");
    const ts = courseInfoDiv.getAttribute("data-timeslot");

    if (r === null || c === null || ts === null) return;

    const parsedRow = parseInt(r);
    const parsedCol = parseInt(c);
    const parsedTimeslot = parseInt(ts);

    if (destRow.value === parsedRow && destCol.value === parsedCol) {
        clearAdjustPick(); // Clear all selections if clicking the same destination cell
        return;
    }

    if (srcRow.value === parsedRow && srcCol.value === parsedCol) {
        ElMessage.error("待移动课和目的时间不能在同个时间块");
    } else {
        recommendDest.value = [];
        destRow.value = parsedRow;
        destCol.value = parsedCol;
        destTimeslot.value = parsedTimeslot;
    }
};

const adjustConfirm = () => {
    if (srcId.value === null || destTimeslot.value === -1) {
        ElMessage.warning('请先选择待移动的课程和目标时间');
        return;
    }
    ElMessageBox.confirm(
        `将把课程ID ${srcId.value} 调到 ${timeslotConvert(destTimeslot.value)}?`,
        "手动调课",
        {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
        }
    )
    .then(() => {
        adjust(srcId.value, destTimeslot.value);
    })
    .catch(() => {
        ElMessage.info("已取消调课");
    });
};

const adjust = async (currentSrcId, currentDestTimeslot) => {
    try {
        const res = await axios.put(`/api/timetable/adjust/${currentSrcId}/${currentDestTimeslot}`, {}, {
             headers: {
                token: localStorage.getItem("token"),
            },
        });
        ElMessage.success(res.data.msg || "操作成功");
        clearAdjustPick();

        if (classNo.value !== "") {
            queryClass();
        } else if (roomNo.value !== "") {
            queryRoom();
        } else if (teacherNo.value !== "") {
            queryTeacher();
        } else {
            getList();
        }
    } catch (error) {
        console.error("调课失败:", error);
        ElMessage.error(error.response?.data?.msg || "调课失败");
    }
};

const clearAdjustPick = () => {
    srcId.value = null;
    srcRow.value = -1;
    srcCol.value = -1;
    srcTimeslot.value = -1;
    // destId.value = null; // Not used
    destRow.value = -1;
    destCol.value = -1;
    destTimeslot.value = -1;
    recommendDest.value = [];
};

const getConflictList = async (id) => {
    try {
        const res = await axios.get(`/api/timetable/getConfilctList/${id}`, {
            headers: {
                token: localStorage.getItem("token"),
            },
        });
        const list = res.data.data;
        console.log(list);
        if (list.length === 0) {
            ElMessage.info("本节课不存在时间冲突");
        } else {
            let html = "本节课存在的冲突有：";
            list.forEach(item => {
                html += "<br/>" + JSON.stringify(item);
            });
            ElMessageBox.alert(html, "冲突提示", {
                confirmButtonText: "确定",
                dangerouslyUseHTMLString: true,
            });
        }
    } catch (error) {
        console.error("获取冲突列表失败:", error);
        ElMessage.error("获取冲突列表失败");
    }
};

const rehearsalChangeTimeslot = async (id) => {
    try {
        const res = await axios.get(`/api/timetable/rehearsalChangeTimeslot/${id}`, {
            headers: {
                token: localStorage.getItem("token"),
            },
        });
        recommendDest.value = res.data.data || [];
        if (recommendDest.value.length > 0) {
             ElMessage.success("已高亮推荐的无冲突目标时间段");
        } else {
             ElMessage.info("未找到无冲突的可移动时间段");
        }
    } catch (error) {
        console.error("预演调课失败:", error);
        ElMessage.error("预演调课失败");
    }
};

const timeslotConvert = (ts) => {
    if (ts === null || ts < 0) return "未知时间";
    const week = Math.floor(ts / 5) + 1;
    const section = `(${(ts % 5) * 2 + 1}-${(ts % 5) * 2 + 2}节)`;
    return `周${digital2Chinese(week, 'week')}${section}`;
};

const digital2Chinese = (num, identifier) => {
    const character = ["零", "一", "二", "三", "四", "五", "六", "日"]; // Added 日 for week 7
    if (identifier === "week") {
        return num === 7 ? character[7] : character[num] || String(num); // Handle Sunday and fallback for numbers > 6
    }
    return character[num] || String(num); // Fallback for numbers > 6
};

const clearListener = () => {
    classNo.value = "";
    roomNo.value = "";
    teacherNo.value = "";
    // semesterId is not cleared here, assuming it's intentional
    clearAdjustPick();
    getList(); // Refresh list based on current semesterId
};

const handleSelectClass = (val) => {
    classNo.value = val;
    roomNo.value = "";
    teacherNo.value = "";
    clearAdjustPick();
    if (val) queryClass(); else getList();
};

const handleSelectRoom = (val) => {
    roomNo.value = val;
    classNo.value = "";
    teacherNo.value = "";
    clearAdjustPick();
    if (val) queryRoom(); else getList();
};

const handleSelectTeacher = (val) => {
    teacherNo.value = val;
    classNo.value = "";
    roomNo.value = "";
    clearAdjustPick();
    if (val) queryTeacher(); else getList();
};

</script>

<style scoped>
.app-container {
    padding: 20px;
}
.class-table {
    margin-bottom: 20px;
    display: flex;
}
.semester-select,
.class-select {
    margin-right: 10px;
    margin-bottom: 10px; /* Add some bottom margin for better spacing on smaller screens */
}
.period {
    font-size: 12px;
    color: #666;
}
.course-info {
    min-height: 60px; /* Ensure a minimum height for cells */
    padding: 5px;
    font-size: 12px;
    line-height: 1.4;
    position: relative; /* For absolute positioning of '待移动课' span if needed */
}
.mycard {
    border: 1px solid #eee;
    padding: 3px;
    margin-bottom: 3px;
    border-radius: 3px;
    background-color: #f9f9f9;
    cursor: pointer;
}
.mycard:hover {
    background-color: #f0f0f0;
}
.mycard .span { /* Style for the '待移动课' and '目的时间' spans */
    display: block; /* Make it a block to show background color properly */
    margin-bottom: 2px;
    padding: 2px;
    border-radius: 2px;
    font-weight: bold;
    text-align: center;
}
</style>